<template>
    <div class="box" :class="{ 'file_none': !showFileList }">
      <el-upload
        action=""
        :accept="accept"
        v-model:file-list="_fileList"
        :show-file-list="showFileList"
        class="upload-demo width_100 flex"
        :ref="(el) => fileUpload = el"
        :http-request="fnUploadRequest"
        :before-upload="handleUpload"
        :on-preview="onPreview"
        :on-remove="onPemove"
      >
        <el-button type="primary" size="small">{{ title }}</el-button>
      </el-upload>
    </div>
  </template>

<script lang="ts" setup>
import {
    ElMessage,
    dayjs,
} from 'element-plus'
import { EstimatedTime, StrSplit } from '~/src/utils/utils';
import { AxiosPromise } from 'axios';
import request from '~/src/utils/request';
/**
 * @props
 */

const props = defineProps({
    // 导入按钮标题
    title: {
        type: String,
        default: '导入'
    },
    // 接口
    api: {
        type: String,
        default: '/api/dms/product/import'
    },
    // oss接口【一般动不着】
    ossApi: {
        type: String,
        default: '/api/file/getosssts'
    },
    // 参数
    query: {
        type: Object,
        default: () => { return {} }
    },
    // 文件类型
    accept: {
        type: String,
        default: '.xlsx', //'.xlsx,.doc,.pdf' 多文件格式
    },
    // 目录
    directory: {
        type: String,
        default: '',
    },
    // 是否显示文件信息
    showFileList: {
        type: Boolean,
        default: true,
    },
    // 上传文件之前的校验【限制文件大小】
    size: {
        type: Number,
        defailt: ''
    }
})
/**
 * @var
 */
const proxy: any = getCurrentInstance()?.proxy

const fileUpload = ref()
// 文件名称
const fileName = ref('')
// 时间
const todayKey = dayjs().format('YYYY-MM-DD') //当前时间2023-08-07
// 文件夹
const folderName = 'dms' + props.directory //dms/xxx/20230405/xxxx.jpg

// 获取阿里云STS
const getosssts: () => AxiosPromise = () =>
    request(props.ossApi)

// 文件上传接口
const ImportOrExport: (data: object) => AxiosPromise = (data) =>
    request(props.api, { data })

const emit = defineEmits(['Refresh', 'exposePath'])

// 数据
let _fileList = ref<any>([])

/**
 * @method
 */
// 请求
const fnUploadRequest = async (options: any) => {
    const { onSuccess, onProgress, onError, file } = options
    fileName.value = file.name
    try {
        const configRes = await getosssts()
        const client = new OSS({
            region: configRes.data.regionId,
            accessKeyId: configRes.data.AccessKeyId,
            accessKeySecret: configRes.data.AccessKeySecret,
            // 从STS服务获取的安全令牌（SecurityToken）。
            stsToken: configRes.data.SecurityToken,
            // 填写Bucket名称，例如examplebucket。
            bucket: configRes.data.roleSessionName, // bucket名字
            secure: true,
        })

        const chunkSize = 1024 * 1024 * 1// 分片大小
        const chunks = Math.ceil(file.size / chunkSize) // 分片数量
        ElMessage(`预计本次上传需要${EstimatedTime(chunks)}`)
        const updateName = `${folderName}/${todayKey}/${file.name}`
        const porps: any = {
            // 获取分片上传进度、断点和返回值。
            progress: (p: any, cpt: any, res: any) => {
                onProgress({ percent: p * 100 })
                // setProgress(p * 100)
            },
            headers: {},
            parallel: chunks,
            partSize: chunkSize,
            meta: { year: dayjs().format('YYYY'), people: `${folderName}` },
            mime: 'text/plain',
        }
        client.multipartUpload(`${updateName}`, file, { ...porps }).then((res: any) => {

            onSuccess(res, file)
            const requestUrls = res.res.requestUrls[0]
            const path = StrSplit(requestUrls, '?', 0)

            _fileList.value = [
                { name: file.name, url: path }
            ]

            // 暴露oss地址
            emit('exposePath', path)

            if (!props.api) return

            ImportOrExport({
                ...props.query,
                path
            }).then(res => {
                proxy.$Message(`${props.title}成功!`, 'success')
                emit('Refresh')
            }).catch(() => {
                proxy.$Message(`${props.title}失败!`, 'error')
            })

        }).catch(function (err: any) {
            proxy.$Message(`${props.title}失败!`, 'error')
        })

    } catch (error) {
    }
}
// 上传前
const handleUpload = (file: any) => {

    const { size } = file

    // 是否超出限制大小
    let isExceedSize = false

    if (props.size) {
        isExceedSize = size / 1024 / 1024 > props.size

        if (isExceedSize) {
            proxy.$Message(`上传文件大小不能超过 ${props.size}MB!`, 'warning')
            return false
        }
    }
}
// 预览
const onPreview = (file: any) => {
    window.open(file.url)
}
// 删除
const onPemove = (file: any) => {
    _fileList.value = []
}

/**
 * @实例
 */
// 组件实例
defineExpose({
    list: _fileList,
})
</script>

<style lang="scss" scoped>
.default_text {
    padding-top: 12px;
}

.box {
    width: 100%;

    :deep() {
        .el-upload-dragger {
            height: 100%;
            line-height: 80px;
        }

        .el-upload-list__item.is-success.focusing .el-icon-close-tip {
            display: none !important;
        }

        .el-icon--close-tip {
            display: none !important;
        }
    }
}

.file_none {
    .el-upload-list {
        display: none;
    }
}
</style>
